import json
from redis import Redis
from sqlalchemy.orm import Session
from sqlalchemy.sql import func
from app.models import IPWhiteList, RiskRule
from app.common.enums.bz_enum import SysType
from datetime import datetime, timedelta
from app import utils

from app.common.exceptions import GenericException
from app.common.enums.resp_enum import ErrTypes

import logging
logger = logging.getLogger(__name__)

IP_WHITE_LIST_KEY = 'ip_white_list'
RISK_RULE_KEY = 'risk_rule'

def get_risk_rule_list(db: Session):
    #return db.query(IPWhiteList).filter(IPWhiteList.status == 1).order_by(IPWhiteList.create_time.desc()).offset(skip).limit(limit).all()
    return db.query(RiskRule).filter(RiskRule.status == 1).order_by(RiskRule.priority.desc()).all()


def is_ip_in_white_list(r: Redis, ip_addr: str, target_sys: str=SysType.OPENAPI.value[0]) -> bool:
    v = r.get(f'{IP_WHITE_LIST_KEY}:{ip_addr}:{target_sys}')
    if v:
        return True
    else:
        return False

def get_ip_white_list(db: Session):
    #return db.query(IPWhiteList).filter(IPWhiteList.status == 1).order_by(IPWhiteList.create_time.desc()).offset(skip).limit(limit).all()
    return db.query(IPWhiteList).filter(IPWhiteList.status == 1).order_by(IPWhiteList.create_time.desc()).all()

def get_ip_addr(db: Session, ip_addr: str):
    return db.query(IPWhiteList).filter(IPWhiteList.ip_addr == ip_addr).first()

def refresh_ip_whitelist_cache(db: Session, r: Redis):
    '''同步白名单缓存数据'''
    db_ip_list = get_ip_white_list(db)
    ip_list = []
    keys = r.keys(f'{IP_WHITE_LIST_KEY}:*')
    r.delete(*keys)
    for ip in db_ip_list:
        if ip.expire_time:
            seconds = utils.seconds_to_datetime(ip.expire_time)
            cache_key = f'{IP_WHITE_LIST_KEY}:{ip.ip_addr}:{ip.target_system}'
            if seconds > 0:
                r.set(cache_key, ip.ip_addr, ex=seconds)
        else:
            cache_key = f'{IP_WHITE_LIST_KEY}:{ip.ip_addr}:{ip.target_system}'
            r.set(cache_key, ip.ip_addr)
        ip_list.append(f'{ip.ip_addr}:{ip.target_system}')
    return ip_list

def refresh_risk_rule_cache(db: Session, r: Redis):
    '''同步规则缓存数据'''
    db_rules = get_risk_rule_list(db)
    rule_list = []
    keys = r.keys(f'{RISK_RULE_KEY}:*')
    if keys:
        r.delete(*keys)
    for rule in db_rules:
        cache_key = f'{RISK_RULE_KEY}:{rule.rule_code}'
        dt = {
            'rule_code': rule.rule_code,
            'rule_name': rule.rule_name,
            'rule_tpl': rule.rule_tpl,
            'priority': rule.priority
        }
        r.set(cache_key, json.dumps(dt))
        rule_list.append(cache_key)
    return rule_list
